/***************************************************************************
 创建者: 华磊
 开始时间: 2020.8.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2020.5.8 类的具体实现代码编写

 ***************************************************************************/
#include "ecatmotor.h"
#include <qdebug.h>
#include "ethercatVendorId.h"
#include "ethercaterror.h"
#include "messagelog.h"

EcatMotor::EcatMotor(E_DEVICE_PROTOCOL protocolIn, int aliasIn, int busIdIn, int maxChannelIn)
{
    protocol=protocolIn;
    alias=aliasIn;
    busId=busIdIn;
    maxChannel=maxChannelIn;


    memset( (void*)&pdoDomainOffset , D_OD_NOT_USED,  sizeof(ec_off_od) );

    for(int i=0;i<D_MAX_MOTOR_CHANNEL;i++)
    {
       logicMotors[D_MAX_MOTOR_CHANNEL]=NULL;
    }

    for(int i=0;i<D_MAX_MOTOR_CHANNEL;i++)
    {
       logicMotors[i]=new LogicMotor(protocolIn,aliasIn,busIdIn);
    }


    vendorId=D_VENDOR_ID_VIRTUAL;


}

int EcatMotor::checkEthercatDeviceError(bool &isWarningState, bool &isFaultOccurred, unsigned int &errorCodeOut,
                                        unsigned int &vendorIdOut, int &aliasOut)
{

    for(int i=0;i<maxChannel;i++)
    {
        bool tmpisWarningState=false;
        bool tmpisFaultOccurred=false;
        logicMotors[i]->checkEthercatDeviceError(tmpisWarningState,tmpisFaultOccurred,errorCodeOut,vendorIdOut,aliasOut);
        if(tmpisFaultOccurred)
        {
            isFaultOccurred=true;
            addMsg(ENUM_MSG_ERROR, "RobotBase", "EcatMotor", 5034,
                   -1,
                   aliasOut,
                   errorCodeOut,
                   vendorIdOut,i );
            return 0;
        }
        if(tmpisWarningState)
        {
            isWarningState=true;
            addMsg(ENUM_MSG_WARNING, "RobotBase", "EcatMotor", 5041,
                   -1,
                   aliasOut,
                   errorCodeOut,
                   vendorIdOut,i );
            return 0;
        }
    }
    return 1;
}

int EcatMotor::checkCanopenDeviceError(bool &isWarningState, bool &isFaultOccurred, unsigned int &errorCodeOut,
                                       unsigned int &vendorIdOut, int &aliasOut)
{
    for(int i=0;i<maxChannel;i++)
    {
        bool tmpisWarningState=false;
        bool tmpisFaultOccurred=false;
        logicMotors[i]->checkCanopenDeviceError(tmpisWarningState,tmpisFaultOccurred,errorCodeOut,vendorIdOut,aliasOut);
        if(tmpisFaultOccurred)
        {
            isFaultOccurred=true;
            addMsg(ENUM_MSG_ERROR, "RobotBase", "EcatMotor", 5034,
                   -1,
                   aliasOut,
                   errorCodeOut,
                   vendorIdOut,i );
            return 0;
        }
        if(tmpisWarningState)
        {
            isWarningState=true;
            addMsg(ENUM_MSG_WARNING, "RobotBase", "EcatMotor", 5041,
                   -1,
                   aliasOut,
                   errorCodeOut,
                   vendorIdOut,i );
            return 0;
        }
    }
    return 1;
}

bool EcatMotor::isErrorOccured()
{
    for(int i=0;i<maxChannel;i++)
    {
       if(0!=logicMotors[i]->errorCode)
       {
           addMsg(ENUM_MSG_ERROR, "RobotBase", "EcatMotor", 5034,
                  -1,
                  alias,
                  logicMotors[i]->errorCode,
                  vendorId,i );
           return true;
       }
    }
    false;
}




int EcatMotor::setSdoList(QVector<SdoConfig> &sdoConfigListIn)
{
    sdoConfigList=sdoConfigListIn;
    return 1;
}

int EcatMotor::getSdoList(QVector<SdoConfig> &sdoConfigListOut)
{
    sdoConfigListOut=sdoConfigList;
    return 1;
}

int EcatMotor::getVendorId()
{
    return vendorId;

}

int EcatMotor::setVendorId(int vendorIdIn)
{
    vendorId=vendorIdIn;
    for(int i=0;i<maxChannel;i++)
    {
        logicMotors[i]->setVendorId(vendorIdIn);
    }
//    qDebug()<<"EcatMotor::setVendorId vendorId="<<vendorId;
    return 1;

}


int EcatMotor::getAlias()
{
    return alias;
}

int EcatMotor::getProtocol()
{
    return protocol;
}


void EcatMotor::updateMotorState()
{

    if(protocol==E_DEVICE_PROTOCOL_MODBUS_RTU || protocol==E_DEVICE_PROTOCOL_MODBUS_TCP)
    {
        for(int i=0;i<maxChannel;i++)
        {
            updateModbusMotorState(i);
        }

        return ;
    }
    else if(protocol==E_DEVICE_PROTOCOL_ETHERCAT || protocol==E_DEVICE_PROTOCOL_CANOPEN)
    {
        for(int i=0;i<maxChannel;i++)
        {
            updateEthercatMotorState(i);
        }
       return ;
    }

    return ;


}

void EcatMotor::updateEthercatMotorState(int channel)
{
    logicMotors[channel]->updateEthercatMotorState();
}


void EcatMotor::updateModbusMotorState(int channel)
{
    logicMotors[channel]->updateModbusMotorState();
    return ;
}


void EcatMotor::addMsg(int messageLevel,
                       std::string componentName,
                       std::string messageType,
                       int messageCode,
                       int _robotId,
                       int parameter1 ,
                       int parameter2 ,
                       int parameter3 ,
                       int parameter4  )
{

    struct timeval tv_begin ;
    gettimeofday(&tv_begin, NULL);

    Message tmpMsg;
    tmpMsg.MessageLevel = messageLevel;
    tmpMsg.componentClassName = componentName;
    tmpMsg.messageType = messageType;
    tmpMsg.robotId = _robotId;
    tmpMsg.messageCode = messageCode;
    tmpMsg.time = tv_begin.tv_sec;

    QString infomationStr;

    switch(messageCode)
    {

    case 5034:
    {
        QString tempError;
        QString errorInfo=EthercatError::geterror( parameter3, parameter2 );
        tempError.clear();
        tempError.sprintf("%02x",parameter2);
        infomationStr =  QObject::tr("伺服报警:机器人:")  + QString::number(_robotId)
                + QObject::tr(", 别名:") + QString::number(parameter1)
                + QObject::tr(", channel:") + QString::number(parameter4)
                + QObject::tr(", 错误码:0x")  + tempError+" ,";
        infomationStr+=errorInfo;
    }
        break;

    case 5041:
    {
        QString tempError;
        tempError.sprintf("%02x",parameter2);
        infomationStr =  QObject::tr("机器人:")  + QString::number(_robotId)
        + QObject::tr(", 别名:") + QString::number(parameter1)
        + QObject::tr(", channel:") + QString::number(parameter4)
         +  " ," + QObject::tr("伺服发生警告,警告码 :0x")+ tempError
                + EthercatError::getwarn( parameter3, parameter2 );
    }
        break;

    }

    tmpMsg.MessageInformation = infomationStr.toStdString();
    MessageLog::getInstance()->addMessage(tmpMsg);
}

